home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 003 / ff / number.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  4KB  |  167 lines

  1. /* Copyright (c) 1982, 1985 Gary Perlman */
  2. /* Copies can be made if not for material gain */
  3.  
  4. /*
  5.     number: report if a string is a UNIX formatted number
  6.  
  7.     notes:
  8.         a number in UNIX is one that can be converted from
  9.         a string to an integer or real with no loss of information
  10.             due to bad format
  11.         all numbers can be surrounded by whitespace
  12.         an integer has an optional minus sign, followed by digits
  13.         a real number has an optional minus sign followed by digits
  14.         if a string has a decimal point, followed by zeros, it is real, not int
  15.  
  16.     value:
  17.         1 is string is an integer [-] 0-9+
  18.         2 is string is a real number (as seen by atof)
  19.         0 for non-numbers
  20.  
  21.     compilation flags:
  22.         -DSTANDALONE    includes test main program
  23.         $Compile: cc -DSTANDALONE -O -o %F %f
  24.     
  25.     deficiencies:
  26.         does not check to see if significant digits will be ignored
  27.     
  28.     author:
  29.         Gary Perlman
  30.  
  31.     date:
  32.         Wed May 22 13:30:40 EDT 1985
  33.         Sun Sep  1 14:53:51 EDT 1985 (modified test module)
  34.         
  35. */
  36. #include <ctype.h>
  37.  
  38. #ifndef lint
  39. static char sccsfid[] = "@(#) number.c 5.2 (unix|stat) 9/1/85";
  40. #endif
  41.  
  42. #define    IS_NOT      0            /* not a number */
  43. #define    IS_INT      1            /* an integer */
  44. #define    IS_REAL     2            /* a real number */
  45.  
  46. #define    EOS         '\0'
  47.  
  48. /*LINTLIBRARY*/
  49.  
  50. number (string)
  51. char    *string;                 /* the string to be tested */
  52.     {
  53.     int     answer = IS_INT;     /* start by assuming it is an integer */
  54.     int     before = 0;          /* anything before the decimal? */
  55.     int     after = 0;           /* anything after the decimal? */
  56.     while (isspace (*string))    /* skip over blank space */
  57.         string++;
  58.     if (*string == EOS)          /* empty string not allowed */
  59.         return (IS_NOT);
  60.     if (*string == '+' || *string == '-') /* old atoi didn't allow '+' */
  61.         {
  62.         string++;
  63.         if (!isdigit (*string) && *string != '.')
  64.             return (IS_NOT);
  65.         }
  66.     if (isdigit (*string))       /* note that there was a digit before . */
  67.         {
  68.         before = 1;
  69.         while (isdigit (*string))
  70.             string++;
  71.         }
  72.     if (*string == '.')          /* found a decimal point, parse for real */
  73.         {
  74.         answer = IS_REAL;
  75.         string++;
  76.         if (isdigit (*string))   /* note that there was a digit after . */
  77.             {
  78.             after = 1;
  79.             while (isdigit (*string))
  80.                 string++;
  81.             }
  82.         }
  83.     if (!before && !after)       /* must be digit somewhere */
  84.         return (IS_NOT);
  85.     if (*string == 'E' || *string == 'e') /* exponent */
  86.         {
  87.         answer = IS_REAL;
  88.         string++;
  89.         if (*string == '+' || *string == '-') /* optional sign */
  90.             string++;
  91.         if (!isdigit (*string))  /* missing exponent */
  92.             return (IS_NOT);
  93.         while (isdigit (*string))
  94.             string++;
  95.         }
  96.     while (isspace (*string))    /* skip optional spaces */
  97.         string++;
  98.     /* should now have exhausted the input string */
  99.     return (*string == EOS ? answer : IS_NOT);
  100.     }
  101.  
  102. #ifdef STANDALONE
  103.  
  104. #include <stdio.h>
  105. /*
  106.     exits with status = the number of args not numerical
  107.     Shell Example:
  108.         if number -i $*
  109.         then
  110.             echo processing $*
  111.         else
  112.             echo $0: arguments must be integers 
  113.         fi
  114.     Options:
  115.         -i  arguments must be integer
  116.         -n  arguments must be non-negative
  117. */
  118. int     NoNegative;   /* do the values have to be non-negative? */
  119. int     Integer;      /* do the values have to be integers? */
  120.  
  121. static
  122. int
  123. initial (argc, argv) char **argv;
  124.     {
  125.     extern    char    *optarg;
  126.     extern    int     optind;
  127.     int     errflg = 0;
  128.     int     C;
  129.     char    *optstring = "in";
  130.     char    *usage = "[-in] string ...";
  131.     while ((C = getopt (argc, argv, optstring)) != EOF)
  132.         switch (C)
  133.             {
  134.             case 'i': Integer = 1; break;
  135.             case 'n': NoNegative = 1; break;
  136.             default: errflg++; break;
  137.             }
  138.     if (errflg)
  139.         {
  140.         fprintf (stderr, "Usage: %s %s\n", argv[0], usage);
  141.         exit (1);
  142.         }
  143.     return (optind);
  144.     }
  145.  
  146. main (argc, argv) char **argv;
  147.     {
  148.     int     status = 0;
  149.     int     arg = initial (argc, argv);
  150.     char    *string;
  151.     while (arg < argc)
  152.         {
  153.         string = argv[arg++];
  154.         if (NoNegative && *string == '-') status++;
  155.         else switch (number (string))
  156.             {
  157.             case IS_NOT:  status++; break;
  158.             case IS_REAL: if (Integer) status++; break;
  159.             case IS_INT:  break;
  160.             default: /* CAN'T HAPPEN */ break;
  161.             }
  162.         }
  163.     exit (status);
  164.     }
  165.  
  166. #endif
  167.